/*
 * Author: Jeff Liu(jebberwocky@gmail.com)
 * Date: Sep 5, 2010 7:42:07 PM
 * 
 * License: MIT
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package org.gglgeo.impl;


import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.gglgeo.api.GeoObjParser;
import org.gglgeo.core.GeoResultStatus;
import org.gglgeo.ggl.GeoLatLng;
import org.gglgeo.ggl.GeoObj.AddressComponent;
import org.gglgeo.ggl.GeoResult;
import org.gglgeo.ggl.GeoObj;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.json.simple.JSONArray;;

/**
 * The Class JsonDetectParser.
 * using json-simple @see code.google.com/p/json-simple
 */
public class JsonGeoObjParser implements GeoObjParser {

	@Override
	public GeoResult parse(String text) {
		GeoResult georesult = new GeoResult();
		if(text==null)
			return GeoResult.NotDefinedResult;
		JSONObject o =  (JSONObject)JSONValue.parse(text);
		String _status = (String)o.get("status");
		georesult.setStatus(GeoResultStatus.get(_status));
		JSONArray results = (JSONArray)o.get("results");
		List<GeoObj> objs = new LinkedList<GeoObj>();
		Iterator itr = results.iterator();
		while(itr.hasNext()){
			JSONObject obj = (JSONObject)itr.next();
			GeoObj go = new GeoObj();
			
			go.setFormattedAddress((String)obj.get("formatted_address"));
			
			JSONArray jtypes = (JSONArray)obj.get("types");
			List<String> stypes = new LinkedList<String>();
			Iterator _itr = jtypes.iterator();
			while(_itr.hasNext())
				stypes.add((String)_itr.next());
			go.setTypes(stypes);
			
			JSONArray addComps = (JSONArray)obj.get("address_components");
			go.setAddressComponents(new LinkedList<AddressComponent>());
			Iterator aciter = addComps.iterator();
			while(aciter.hasNext()){
				AddressComponent acomp = go.new AddressComponent();
				acomp.setTypes(new LinkedList<String>());
				JSONObject jo = (JSONObject)aciter.next();
				acomp.setLongName((String)jo.get("long_name"));
				acomp.setShortName((String)jo.get("short_name"));
				JSONArray _jarray = (JSONArray)jo.get("types");
				Iterator __itr = _jarray.iterator();
				while(__itr.hasNext())
					acomp.getTypes().add((String)__itr.next());
				go.getAddressComponents().add(acomp);
			}
			
			
			go.setGeometry(go.new GeometryClass());
			JSONObject geo = (JSONObject)obj.get("geometry");
			JSONObject geo_location = (JSONObject)geo.get("location");
			go.getGeometry().setLocation(new GeoLatLng(
					(Double)geo_location.get("lat"),
					(Double)geo_location.get("lng")
					));
			go.getGeometry().setLocationType((String)geo.get("location_type"));
			
			JSONObject viewpoint = (JSONObject)geo.get("viewport");
			JSONObject vwne = (JSONObject)viewpoint.get("northeast");
			JSONObject vwsw = (JSONObject)viewpoint.get("southwest");
			
			GeoLatLng viewPortNE = new GeoLatLng(
					(Double)vwne.get("lat"),
					(Double)vwne.get("lng")
					);
			go.getGeometry().setViewPortNE(viewPortNE);
			
			GeoLatLng viewPortSW = new GeoLatLng(
					(Double)vwsw.get("lat"),
					(Double)vwsw.get("lng")
					);
			go.getGeometry().setViewPortSW(viewPortSW );
			objs.add(go);
		}
		georesult.setResults(objs);
		return georesult;
	}

}
